<template>
  <div class="pest-detection-container">
    <!-- 左侧面板 -->
    <div class="left-panel">
      <!-- 图片上传区域 -->
      <div class="upload-card">
        <div class="card-header">
          <i class="el-icon-picture-outline"></i>
          <span>校园害虫检测</span>
          <el-tooltip content="点击图片区域可重新上传" placement="top">
            <i class="el-icon-info"></i>
          </el-tooltip>
        </div>
        <div class="upload-area" @click="handleUploadClick">
          <img v-if="imageUrl" :src="imageUrl" class="uploaded-image" />
          <div v-else class="upload-placeholder">
            <i class="el-icon-upload"></i>
            <div>点击上传害虫图片</div>
          </div>
          <input ref="fileInput" type="file" accept="image/*" style="display: none" @change="handleFileChange" />
        </div>
      </div>

      <!-- 检测结果区域 -->
      <div class="result-card">
        <div class="card-header">
          <i class="el-icon-document"></i>
          <span>检测结果</span>
          <el-tag v-if="detectionTime" size="mini" type="info">
            检测时间: {{ detectionTime }}
          </el-tag>
        </div>
        <el-table :data="detectionResults" stripe style="width: 100%" height="400px" v-loading="loading">
          <el-table-column prop="accuracy" label="置信度" width="120" sortable>
            <template slot-scope="{ row }">
              <div style="display: flex; align-items: center;">
                <el-progress :percentage="row.accuracy" :color="getProgressColor(row.accuracy)" :show-text="false"
                             :stroke-width="12" style="flex: 1; margin-right: 10px;" />
                <span>{{ row.accuracy }}%</span>
              </div>
            </template>
          </el-table-column>
          <el-table-column prop="category" label="分类" width="150">
            <template slot-scope="{ row }">
              <el-tag :type="getPestTypeColor(row.category)" size="small">
                {{ row.category || '暂无' }}
              </el-tag>
            </template>
          </el-table-column>
          <el-table-column prop="name" label="害虫名称" width="150">
            <template slot-scope="{ row }">
              <span :class="{ 'danger-text': row.danger }">
                {{ row.name }}
                <el-tag v-if="row.danger" size="mini" type="danger">有害</el-tag>
              </span>
            </template>
          </el-table-column>
          <el-table-column prop="livingHabits" label="生活习性" show-overflow-tooltip>
            <template slot-scope="{ row }">
              <span v-if="row.livingHabits">{{ row.livingHabits }}</span>
              <span v-else class="no-livingHabits">暂无描述</span>
            </template>
          </el-table-column>
          <el-table-column label="操作" width="120" align="center">
            <template slot-scope="{ row, $index }">
              <el-button type="text" size="small" @click.stop="viewPestInfo(row)">
                详情
              </el-button>
              <el-button type="text" size="small" @click.stop="confirmDelete(row, $index)" style="color: red">
                删除
              </el-button>
            </template>
          </el-table-column>
        </el-table>

        <div style="text-align:center; margin-top:0px">
          <el-pagination
              background
              :current-page="params.pageNum"
              :page-size="params.pageSize"
              :total="total"
              layout="prev, pager, next"
              @current-change="handlePageChange"
          />
        </div>
      </div>
    </div>

    <!-- 右侧面板 -->
    <div class="right-panel">
      <!-- 搜索区域 -->
      <div class="search-card">
        <div class="card-header">
          <i class="el-icon-search"></i>
          <span>害虫搜索</span>
        </div>
        <div class="search-box">
          <el-input v-model="searchQuery" placeholder="输入害虫名称搜索" clearable @keyup.enter.native="handleSearch"
                    @clear="handleClearSearch">
            <i slot="prefix" class="el-icon-search"></i>
          </el-input>
          <el-button type="primary" icon="el-icon-search" @click="handleSearch" :loading="searchLoading">
            搜索
          </el-button>
        </div>
      </div>

      <!-- 历史记录区域 -->
      <div class="history-card">
        <div class="card-header">
          <i class="el-icon-time"></i>
          <span>检测历史</span>
          <el-button type="text" size="mini" @click="clearHistory" :disabled="historyData.length === 0">
            清空历史
          </el-button>
        </div>
        <el-table :data="historyData" height="100%" style="width: 100%" empty-text="暂无检测历史">
          <el-table-column prop="time" label="检测时间" width="180">
            <template slot-scope="{ row }">
              <el-tooltip :content="row.time" placement="top">
                <span>{{ formatTime(row.time) }}</span>
              </el-tooltip>
            </template>
          </el-table-column>
          <el-table-column prop="result" label="检测结果">
            <template slot-scope="{ row }">
              <div class="result-summary">
                <span v-for="(item, index) in row.results" :key="index">
                  <span :class="{ 'danger-text': item.danger }">{{ item.name }}</span>
                  <span v-if="index < row.results.length - 1">, </span>
                </span>
              </div>
            </template>
          </el-table-column>
          <el-table-column label="操作" width="100" align="center">
            <template slot-scope="{ row }">
              <el-button type="text" size="small" @click.stop="viewHistoryDetail(row)">
                详情
              </el-button>
            </template>
          </el-table-column>
        </el-table>
      </div>
    </div>

    <!-- 上传对话框 -->
    <el-dialog :visible.sync="uploadDialogVisible" title="上传害虫图片" width="500px" :close-on-click-modal="false">
      <el-upload class="upload-dialog" drag action="#" :auto-upload="false" :show-file-list="false"
                 :on-change="handleDialogUpload">
        <i class="el-icon-upload"></i>
        <div class="el-upload__text">将图片拖到此处，或<em>点击上传</em></div>
        <div class="el-upload__tip" slot="tip">
          支持JPG/PNG格式，大小不超过5MB
        </div>
      </el-upload>
      <div slot="footer" class="dialog-footer">
        <el-button @click="uploadDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="confirmUpload" :disabled="!selectedFile">
          确认上传
        </el-button>
      </div>
    </el-dialog>

    <el-dialog :visible.sync="pestDetailVisible" :title="pestDetail.name + ' - 详情'" width="800px" :close-on-click-modal="false" center>
      <div class="pest-detail-content" style="max-height: 600px; overflow-y: auto; padding: 24px;">
        <h3 style="font-weight:bold; font-size:20px; margin-bottom:16px;">{{ pestDetail.name }}</h3>

        <h4 style="font-weight:bold; margin: 12px 0 8px 0;">基本信息</h4>
        <div style="margin-bottom: 18px; line-height: 1.8; color: #333;">
          {{ pestDetail.basicInformation || '暂无基本信息' }}
        </div>

        <h4 style="font-weight:bold; margin: 12px 0 8px 0;">分类</h4>
        <div style="margin-bottom: 18px;">
          <el-tag :type="getPestTypeColor(pestDetail.category)" size="medium">
            {{ pestDetail.category || '暂无分类信息' }}
          </el-tag>
        </div>

        <h4 style="font-weight:bold; margin: 12px 0 8px 0;">形态特征</h4>
        <div style="margin-bottom: 18px; line-height: 1.8; color: #333;">
          {{ pestDetail.morphologicalCharacteristics || '暂无形态特征描述' }}
        </div>

        <h4 style="font-weight:bold; margin: 12px 0 8px 0;">生活习性</h4>
        <div style="margin-bottom: 18px; line-height: 1.8; color: #333;">
          {{ pestDetail.livingHabits || '暂无生活习性描述' }}
        </div>

        <h4 style="font-weight:bold; margin: 12px 0 8px 0;">发生规律</h4>
        <div style="margin-bottom: 18px; line-height: 1.8; color: #333;">
          {{ pestDetail.occurrencePattern || '暂无发生规律描述' }}
        </div>

        <h4 style="font-weight:bold; margin: 12px 0 8px 0;">危害特点</h4>
        <div style="margin-bottom: 18px; line-height: 1.8; color: #333;">
          {{ pestDetail.hazardCharacteristics || '暂无危害特点描述' }}
        </div>

        <h4 style="font-weight:bold; margin: 12px 0 8px 0;">防治方法</h4>
        <div style="margin-bottom: 18px; line-height: 1.8; color: #333;">
          {{ pestDetail.controlMethods || '暂无防治方法' }}
        </div>

        <!-- 害虫图片 -->
        <h4 style="font-weight:bold; margin: 12px 0 8px 0;">害虫图片</h4>
        <div style="margin-bottom: 18px;">
          <div v-if="pestDetail.cover && pestDetail.cover.length" class="image-gallery">
            <el-image
                v-for="(img, index) in pestDetail.cover"
                :key="index"
                :src="img"
                :preview-src-list="pestDetail.cover"
                class="image-item"
                fit="cover"
                lazy>
              <div slot="error" class="image-slot">
                <i class="el-icon-picture-outline"></i>
                <div>图片加载失败</div>
              </div>
            </el-image>
          </div>
          <div v-else class="no-image">暂无图片</div>
        </div>

        <h4 style="font-weight:bold; margin: 12px 0 8px 0;">创建时间</h4>
        <div style="margin-bottom: 18px; line-height: 1.8; color: #333;">
          {{ formatDate(pestDetail.createTime) || '未知' }}
        </div>
      </div>
    </el-dialog>

    <el-dialog title="提示" :visible.sync="deleteDialogVisible" width="300px" :close-on-click-modal="false">
      <span>确定要删除该条数据吗？</span>
      <span slot="footer" class="dialog-footer">
        <el-button @click="cancelDelete">取消</el-button>
        <el-button type="primary" @click="handleDelete">确定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
import axios from 'axios'

// 如果后端和前端不同源，请修改 baseURL
axios.defaults.baseURL = 'http://localhost:9090/api'

export default {
  name: 'PestDetection',
  data () {
    return {
      imageUrl: '',
      searchQuery: '',
      loading: false,
      searchLoading: false,
      uploadDialogVisible: false,
      pestDetailVisible: false,
      selectedFile: null,
      detectionTime: null,
      detectionResults: [],
      total: 0,
      historyData: [],
      pestDetail: {
        id: null,
        name: '',
        basicInformation: '',
        morphologicalCharacteristics: '',
        livingHabits: '',
        occurrencePattern: '',
        hazardCharacteristics: '',
        controlMethods: '',
        category: '',
        createTime: null
      },
      deleteDialogVisible: false,
      deleteRow: null,
      deleteIndex: null,
      params: {
        pageNum: 1,
        pageSize: 5,
        name: ''
      },
      uploadLoading: false
    }
  },
  created () {
    this.load()
    this.loadHistory()
  },
  methods: {
    load () {
      this.loading = true
      axios.get('/pest/page', { params: this.params })
          .then(res => {
            if (res.data.code === '200') {
              this.detectionResults = res.data.data.list || []
              this.total = res.data.data.total || 0
              this.detectionResults.forEach(item => {
                item.accuracy = Math.floor(Math.random() * 40) + 60
                item.danger = true
              })
              this.detectionTime = this.getCurrentDateTime()
            } else {
              this.$message.error('获取分页数据失败')
            }
          })
          .catch(err => {
            console.error(err)
            this.$message.error('获取数据失败')
          })
          .finally(() => { this.loading = false })
    },
    loadHistory () {
      axios.get('/pest/list')
          .then(res => {
            if (res.data.code === '200') {
              this.historyData = res.data.data.map(item => ({
                time: item.createTime,
                results: [{name: item.name, danger: true}]
              }))
            } else {
              this.$message.error('获取历史记录失败')
            }
          })
          .catch(err => console.error(err))
    },
    handlePageChange(page) {
      this.params.pageNum = page
      this.load()
    },
    getCurrentDateTime() {
      const now = new Date()
      const pad = n => n.toString().padStart(2, '0')
      return `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())} ${pad(now.getHours())}:${pad(now.getMinutes())}:${pad(now.getSeconds())}`
    },
    formatDate(dateString) {
      if (!dateString) return ''
      const date = new Date(dateString)
      const pad = n => n.toString().padStart(2, '0')
      return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`
    },
    formatTime(timeString) {
      if (!timeString) return ''
      const date = new Date(timeString)
      const pad = n => n.toString().padStart(2, '0')
      return `${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad(date.getHours())}:${pad(date.getMinutes())}`
    },
    getPestTypeColor(category) {
      const map = {
        '蜱螨目': 'danger',
        '膜翅目': 'warning',
        '双翅目': 'danger',
        '缨翅目': 'success',
        '直翅目': 'danger',
        '同翅目/半翅目（刺吸类）': 'warning',
        '半翅目': 'danger',
        '鳞翅目': 'success',
        '鞘翅目': 'danger'
      }
      return map[category] || 'info'
    },
    viewPestInfo(row) {
      axios.get(`/pest/${row.id}`).then(res => {
        if (res.data.code === '200') {
          this.pestDetail = res.data.data

          // ✅ 获取图片列表
          axios.get(`/pest/image/list/${row.id}`).then(imgRes => {
            let urlList = []
            if (imgRes.data.code === '200' && Array.isArray(imgRes.data.data)) {
              urlList = imgRes.data.data // 后端返回字符串数组
            }
            this.$set(this.pestDetail, 'cover', urlList)
            console.log('检测页-图片地址已转换：', urlList)
          }).catch(() => {
            this.$set(this.pestDetail, 'cover', [])
          })

          this.pestDetailVisible = true
        } else {
          this.$message.error('获取害虫详情失败')
        }
      }).catch(err => console.error(err))
    },
    handleUploadClick() {
      this.uploadDialogVisible = true
    },
    handleFileChange(e) {
      const files = e.target.files
      if (!files.length) return
      this.selectedFile = {raw: files[0]}
      this.previewImage(files[0])
    },
    handleDialogUpload(uploadFile) {
      this.selectedFile = uploadFile
      this.previewImage(uploadFile.raw)
    },
    previewImage(file) {
      if (!file.type.startsWith('image/')) {
        this.$message.error('请选择图片文件')
        return
      }
      if (file.size > 5 * 1024 * 1024) {
        this.$message.error('图片大小不能超过5MB')
        return
      }
      const reader = new FileReader()
      reader.onload = e => {
        this.imageUrl = e.target.result
      }
      reader.readAsDataURL(file)
    },
    async uploadFiles(files) {
      try {
        const saveResp = await axios.post('/pest/save', {
          name: '待识别害虫',
          categories: ['未知'],
          description: '',
          author: '系统',
          foundTime: new Date(),
          location: '未知'
        })
        if (saveResp.data.code !== '200') {
          this.$message.error('创建记录失败: ' + (saveResp.data.msg || ''))
          return
        }
        const pestId = saveResp.data.data
        const formData = new FormData()
        files.forEach(file => formData.append('file', file))
        const uploadResp = await axios.post(`/pest/upload/${pestId}/images`, formData, {
          headers: {'Content-Type': 'multipart/form-data'}
        })
        if (uploadResp.data.code === '200') {
          this.$message.success('上传成功')
          this.load()
          this.loadHistory()
        } else {
          this.$message.error('图片上传失败: ' + (uploadResp.data.msg || ''))
        }
      } catch (err) {
        this.$message.error('上传失败: ' + (err.response?.data?.msg || err.message))
      } finally {
        this.$refs.fileInput.value = ''
      }
    },
    confirmUpload() {
      if (!this.selectedFile) {
        this.$message.warning('请先选择图片')
        return
      }
      this.uploadDialogVisible = false
      this.uploadFiles([this.selectedFile.raw])
    },
    handleClearSearch() {
      this.params.name = ''
      this.load()
    },
    handleSearch() {
      if (!this.searchQuery.trim()) {
        this.$message.warning('请输入搜索内容')
        return
      }
      this.searchLoading = true
      this.params.name = this.searchQuery
      this.load()
      setTimeout(() => {
        this.searchLoading = false
      }, 800)
    },
    viewHistoryDetail(row) {
      axios.get('/pest/list')
          .then(res => {
            if (res.data.code === '200') {
              const pest = res.data.data.find(item => item.createTime === row.time)
              if (pest) {
                this.pestDetail = pest
                this.pestDetailVisible = true
              }
            } else {
              this.$message.error('获取历史详情失败')
            }
          })
          .catch(err => console.error(err))
    },
    clearHistory() {
      this.$confirm('确定要清空所有检测历史吗?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.historyData = []
        this.$message.success('历史记录已清空')
      }).catch(() => {
      })
    },
    getProgressColor(percentage) {
      if (percentage > 90) return '#67C23A'
      if (percentage > 70) return '#409EFF'
      if (percentage > 50) return '#E6A23C'
      return '#F56C6C'
    },
    confirmDelete(row, index) {
      this.deleteDialogVisible = true
      this.deleteRow = row
      this.deleteIndex = index
    },
    handleDelete() {
      this.deleteDialogVisible = false
      axios.delete(`/pest/delete/${this.deleteRow.id}`)
          .then(res => {
            if (res.data.code === '200') {
              this.$message.success('删除成功')
              this.load()
              this.loadHistory()
            } else {
              this.$message.error('删除失败: ' + (res.data.msg || ''))
            }
          })
          .catch(err => console.error(err))
          .finally(() => {
            this.deleteRow = null
            this.deleteIndex = null
          })
    },
    cancelDelete() {
      this.deleteDialogVisible = false
      this.deleteRow = null
      this.deleteIndex = null
    }
  }
}
</script>

<style scoped>
@import url('https://unpkg.com/element-ui/lib/theme-chalk/index.css');

.pest-detection-container {
  display: flex;
  height: calc(100vh - 84px);
  padding: 20px;
  background-color: #f5f7fa;
  position: relative;
  gap: 20px;
}

.pest-detection-container .left-panel {
  flex: 0 0 60%;
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.pest-detection-container .right-panel {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.pest-detection-container .card-header {
  display: flex;
  align-items: center;
  padding: 12px 16px;
  border-bottom: 1px solid #ebeef5;
  background-color: #f8f9fa;
  border-radius: 4px 4px 0 0;
  font-weight: 500;
  color: #333;
}

.pest-detection-container .card-header i {
  margin-right: 8px;
  font-size: 16px;
}

.pest-detection-container .card-header .el-tag,
.pest-detection-container .card-header .el-button {
  margin-left: auto;
}

.pest-detection-container .upload-card,
.pest-detection-container .result-card,
.pest-detection-container .search-card,
.pest-detection-container .history-card {
  background-color: #fff;
  border-radius: 4px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

.pest-detection-container .upload-card .upload-area {
  flex: 1;
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 20px;
  cursor: pointer;
  transition: all 0.3s;
  min-height: 300px;
}

.pest-detection-container .upload-card .upload-area:hover {
  background-color: #f5f7fa;
}

.pest-detection-container .upload-card .uploaded-image {
  max-width: 100%;
  max-height: 300px;
  object-fit: contain;
  border-radius: 4px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.pest-detection-container .upload-card .upload-placeholder {
  display: flex;
  flex-direction: column;
  align-items: center;
  color: #909399;
  font-size: 14px;
}

.pest-detection-container .upload-card .upload-placeholder i {
  font-size: 48px;
  margin-bottom: 16px;
}

.pest-detection-container .result-card {
  flex: 1;
}

.pest-detection-container .result-card .el-table {
  flex: 1;
}

.pest-detection-container .result-card .danger-text {
  color: #f56c6c;
  font-weight: 500;
}

.pest-detection-container .result-card .no-livingHabits {
  color: #c0c4cc;
  font-style: italic;
}

.pest-detection-container .result-card .el-progress {
  display: inline-block;
  width: 60px;
  margin-right: 8px;
  vertical-align: middle;
}

.pest-detection-container .search-card .search-box {
  padding: 20px;
  display: flex;
  gap: 10px;
}

.pest-detection-container .search-card .search-box .el-input {
  flex: 1;
}

.pest-detection-container .history-card {
  flex: 1;
}

.pest-detection-container .history-card .el-table {
  flex: 1;
}

.pest-detection-container .history-card .result-summary {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.upload-dialog {
  text-align: center;
  padding: 20px;
}

.upload-dialog .el-upload-dragger {
  padding: 40px 20px;
}

.upload-dialog .el-upload__tip {
  margin-top: 10px;
  color: #909399;
}

@media (max-width: 992px) {
  .pest-detection-container {
    flex-direction: column;
    height: auto;
  }

  .pest-detection-container .left-panel,
  .pest-detection-container .right-panel {
    flex: 1 1 100%;
  }
}

.image-gallery {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.image-item {
  width: 120px;
  height: 120px;
  border-radius: 4px;
  overflow: hidden;
}

.image-slot {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  height: 100%;
  background: #f5f7fa;
  color: #909399;
  font-size: 30px;
}

.no-image {
  color: #909399;
  font-style: italic;
}
</style>
